<template>
  <Modal
    v-model:active="edgePartitionModalVueActive"
    transfer
    title="边剖分"
    :width="500"
    :append-to-body="true"
    confirm-text="剖分"
    hide-mask
    draggable
    :no-footer="true"
    @close="handleCancel"
  >
    <div class="box">
      <div class="title">
        <div class="title_color"></div>
        <div class="title_content">选择器</div>
      </div>
      <div class="selector-buttons active" :class="{'disabled': bias.enable}">
        <button class="selector-button active" :disabled="bias.enable" @click="onChangeMethod()">
        边
        </button>
        <button class="icon-button" :disabled="bias.enable" @click="handleClear">
          <img src="../../assets/delete.svg" alt="" class="icon imgStyle" />
        </button>
      </div>
      <div class="title">
        <div class="title_color"></div>
        <div class="title_content">参数</div>
      </div>
      <Form :label-width="120" :label-suffix="'：'">
        <FormItem label="尺寸类型">
          <RadioGroup
            v-model:value="parameter.method"
            :options="methodList"
          />
        </FormItem>
        <FormItem label="网格尺寸" v-if="parameter.method === 'meshSize'">
          <NumberInput v-model:value="parameter.meshSize" /> 
        </FormItem>
        <FormItem label="网格数量" v-if="parameter.method === 'number'">
          <NumberInput v-model:value="parameter.number" /> 
        </FormItem>
      </Form>
      <div class="bias-wrap" :class="{'checked': bias.enable}">
        <div class="bias-header"><Checkbox v-model:checked="bias.enable">交互式偏置</Checkbox></div>
        <div class="bias-body" v-if="bias.enable">
          <Form :label-width="94" :label-suffix="'：'">
            <FormItem label="手动调整偏置">
              <Button v-for="item in biasDirections" :key="item.label" @click="(e) => setBiasManual(e, item.label)">{{ item.content }}</Button>
            </FormItem>
            <FormItem label="偏置强度">
              <NumberInput v-model:value="bias.ratio" /> 
            </FormItem>
            <FormItem label="偏置类型">
              <Select v-model:value="bias.style" :options="biasStyles" /> 
            </FormItem>
            <FormItem >
              <Button @click="() => setBias()">设置边</Button>
              <Button @click="setBiasAll">设置全部</Button>
            </FormItem>
          </Form>
        </div>
      </div>
    </div>
    <div class="foot-box">
      <Button type="primary" :disabled="bias.enable" @click="partition">剖分</Button>
      <Button type="default" @click="handleCancel">清空</Button>
    </div>
  </Modal>
</template>
<script setup lang="ts">
import { reactive, watch } from "vue";
import {
  Modal,
  RadioGroup,
  NumberInput,
  Button,
  Form,
  FormItem,
  Checkbox,
  Select,
  Notice,
} from "cax-ui";
import { storeToRefs } from "pinia";
import { useCoreStore, _global } from "@/UI/store";
import { EdgePartitionOptions, SelectedEdgeInfo, STATUS_CODE } from "@/FrontProcessing";

let { edgePartitionModalVueActive } = storeToRefs(useCoreStore());
const coreStore = useCoreStore();

// 剖分的边及其结果
const edgeData: {[key: string | number]: {nodes: number[]; points: number[]}} = {}

const parameter = reactive<{
  method: 'meshSize' | 'number';
  meshSize: number;
  number: number;
}>({
  method: 'meshSize',
  meshSize: 3.5,
  number: 10,
});
const bias = reactive({
  enable: false,
  direction: 0,
  ratio: 2,
  style: 1
})
const methodList = [{
  content: "尺寸",
  label: 'meshSize',
}, {
  content: "数量",
  label: 'number',
}];
const biasDirections = [{
  content: "调整边",
  label: 0,
}, {
  content: "恢复边",
  label: 1,
}]
const biasStyles = [{
  label: "线性的",
  value: 1,
}, {
  label: "双线性的",
  value: 2,
}]

const onChangeMethod = () => {
  coreStore.setEngineState(STATUS_CODE.EDGE)
}
const handleClear = () => {
  _global.Engine.selector.clearAll()
}
const getRatio = async () => {
  const ratio = await _global.Engine.edge.get_ratio(bias.style-1)
  return ratio
  // const val = bias.ratio;
  // // 通过计算获得实际偏置强度，暂时没有
  // return 1.2662394506330028
}
async function setBiasManual(e: any, val: number) {
  // 手动调整偏置- 调整边、恢复边
  // 鼠标左键增加；鼠标左键 + ctrl 时减少；控制ratio参数；
  const direction = val + bias.style;
  const ratio = await getRatio();
  setBias(direction, ratio)
}
function handleMeshBias(options: {entityId: number[]; meshCtrl: EdgePartitionOptions}) {
  _global.Engine.edge
    .edge_mesh_bias(options)
    .then((result: any) => {
      console.log("result", result);   
      // coreStore.setBomInfo(result);
    })
    .catch((err) => {
      Notice.error('需要先选择边')
    })
    .finally(() => {
      // coreStore.setEngineState(0);
    });
}
function setBias(direction?: number, ratio?: number) {
  const currentSelectedEdges = _global.Engine.state.get('currentSelectedEdges');
  const edgeIds = [...currentSelectedEdges.values()].map((item: SelectedEdgeInfo) => item.edgeId);
  edgeIds.forEach(entityId => {
    const data = edgeData[entityId]
    if (!data) {
      Notice.error(`剖分的边中未找到 ${edgeIds[0]}`)
      return
    }
    const number = data.nodes.length - 1
    const meshCtrl: EdgePartitionOptions = {
      bias: {
        direction: direction || bias.style,
        number: number,
        ratio: ratio || (bias.ratio+1)
      }
    }
    handleMeshBias({entityId: [entityId], meshCtrl})
  })
}
function setBiasAll() {
  const edgeIds = Object.keys(edgeData)
  if (!edgeIds.length) {
    Notice.error(`没有找到被剖分的边`)
    return
  }
  edgeIds.forEach((entityId) => {
    const number = edgeData[entityId].nodes.length - 1
    handleMeshBias({
      entityId: [Number(entityId)],
      meshCtrl: {
        bias: {
          direction: bias.style,
          number: number,
          ratio: bias.ratio+1
        }
      }
    })
  })
}
function partition() {
  const meshCtrl: EdgePartitionOptions = {}
  const key = parameter.method;
  meshCtrl[`${key}`] = parameter[key]
  _global.Engine.edge
    .edge_partition(meshCtrl)
    .then((result: any) => {
      console.log("result", result);   
      // coreStore.setBomInfo(result);
      Object.assign(edgeData, result)
    })
    .catch((err) => {})
    .finally(() => {
      // coreStore.setEngineState(0);
    });
}
function handleCancel() {
  edgePartitionModalVueActive.value = false;
}
watch(edgePartitionModalVueActive, (open) => {
  if(open) {
    coreStore.setEngineState(STATUS_CODE.EDGE)
  } else {
    coreStore.setEngineState(STATUS_CODE.NORMAL)
    _global.Engine.edge.leave('elem1dedgemesh')
  }
})
</script>

<style scoped lang="less">
.box {
  padding: 0 16px;
}
.title {
  display: flex;
  align-items: center;
  margin-bottom: 16px;

  .title_color {
    width: 4px;
    height: 12px;
    background: #339af0;
    margin-right: 8px;
  }
  .title_content {
    opacity: 1;
    font-family: PingFang SC;
    font-size: 14px;
    font-weight: 600;
    line-height: 22px;
    letter-spacing: 0em;
    font-variation-settings: "opsz" auto;
    /* content/主要一级primary */
    /* 样式描述：--vxp-content-color-primary */
    color: #212529;
  }
}
.selector-buttons {
  display: flex;
  justify-content: center;
  align-items: center;
  margin-bottom: 16px;
}
.selector-button {
  display: inline-block;
  height: 32px;
  width: 160px;
  padding: 0 16px;
  border: 1px solid #ccc;
  border-top-left-radius: 4px;
  border-bottom-left-radius: 4px;
  font-size: 14px;
  line-height: 30px;
  text-align: center;
  background-color: #fff;
  cursor: pointer;
  outline: none;
  &:disabled {
    cursor: default;
  }
}

.selector-button.active {
  background-color: #e6f7a7;
  /* flex-grow: 1; */
  font-weight: normal;
}
.icon-button {
  width: 32px;
  height: 32px;
  padding: 3px 5px;
  display: flex;
  justify-content: center;
  align-items: center;
  border-top-right-radius: 4px;
  border-bottom-right-radius: 4px;
  border: 1px solid #ccc;
  border-left: none;
  cursor: pointer;
  background-color: #fff;
  &:disabled {
    background-color: #f5f5f5;
    opacity: .66;
    cursor: default;
  }
}
.icon-button:not(:disabled):hover {
  background-color: var(--vxp-color-warning-opacity-7);
}
.imgStyle {
  height: 100%;
}
.box :deep(.vxp-radio--button .vxp-radio__label) {
  padding-left: 12px;
  padding-right: 12px;
}
.bias {
  &-wrap {
    margin-top: 16px;
    position: relative;
    border-top: 1px solid #e6f7a7;
    &.checked {
      border-radius: 8px;
      border: 1px solid #e6f7a7;
    }
  }
  &-header {
    position: absolute;
    top: -11px;
    left: 40px;
    padding: 0 12px;
    background-color: #fff;
  }
  &-body {
    padding: 32px 24px 0;
  }
}
.foot-box {
  margin-top: 20px;
  padding: 8px 12px;
  width: 100%;
  text-align: right;
}
</style>
